package flib;


import java.util.HashMap;
import java.util.TreeMap;
import java.util.Vector;

import processing.core.PGraphics;
import processing.core.PImage;

import flib.Splitter.SplitEvent;


import simpleGeom.HasPos2D;
import simpleGeom.HasPos3D;
import simpleGeom.Triangulator;
import simpleGeom.Vec2D;

public class Plan extends FlibGraph{
	public TreeMap<String, WallType> walltypes=new TreeMap<String, WallType>();
	public TreeMap<String, RoomType> roomtypes=new TreeMap<String, RoomType>();
	public Vector<FlibLevel>levels=new Vector<FlibLevel>();
	public Vector<PImage>images=new Vector<PImage>();
	public Vector<FlibHEdge>splitHEdges=new Vector<FlibHEdge>();
	public Vector<FlibHEdge>triangulate=new Vector<FlibHEdge>();
	public Vector<HasPos2D[]>triangles=new Vector<HasPos2D[]>();
	
	Vector<LevelAnalyser>levelAnalysers=new Vector<LevelAnalyser>();
	public String path;
	public void findConvexCorners(){
		splitHEdges=new Vector<FlibHEdge>();
		for (int i=0;i<rooms.size();i++){
			FlibFace room=rooms.get(i);
			Vector<FlibHEdge>hEdges=room.getHEdges();
			Vector<FlibHENode>nodes=room.getFaceNodes();
			
			for (int j=0;j<nodes.size();j++){
				FlibHENode n1=(FlibHENode) nodes.get(j);
				FlibHENode n2=(FlibHENode) nodes.get((j+1)%nodes.size());
				FlibHENode n3=(FlibHENode) nodes.get((j+2)%nodes.size());
				float angle=(float) Vec2D.getAngleBetweenCCW(n2, n1, n3);
				if (angle<(Math.PI*0.95f)){
					
					Boolean convex=new Boolean(true);
					n2.data=convex;
					Vec2D v=Vec2D.sub(n2, n1);
					Splitter splitter=new Splitter();
					SplitEvent sE=splitter.split(n2, v, hEdges, 0.01f);
					FlibHENode n=this.containsNode2D(sE.s.getX(), sE.s.getY(), nodes, 0.01f);
					if (n==null){
						System.out.println("new Node");
						FlibHENode node2=new FlibHENode(sE.s.getX(), sE.s.getY(),n2.z);
						splitHEdges.add(new FlibHEdge(n2,node2));
					}
					else{
						System.out.println("existing");
						splitHEdges.add(new FlibHEdge(n2,n));
					}
					 v=Vec2D.sub(n2, n3);
					 sE=splitter.split(n2, v, hEdges, 0.01f);
					 n=this.containsNode2D(sE.s.getX(), sE.s.getY(), nodes, 0.01f);
					if (n==null){
						System.out.println("new Node");
						FlibHENode node2=new FlibHENode(sE.s.getX(), sE.s.getY(),n2.z);
						splitHEdges.add(new FlibHEdge(n2,node2));
					}
					else{
						System.out.println("existing");
						splitHEdges.add(new FlibHEdge(n2,n));
					}
					
				}
			}
		}
	}
	
	public void triangulate(){
		triangulate=new Vector<FlibHEdge>();
		for (int i=0;i<rooms.size();i++){
			FlibFace room=rooms.get(i);
			Vector<FlibHENode>nodes=room.simpliFiedOutline();
			Vector<FlibHENode>indnodes=new	Vector<FlibHENode>();
			for (int j=0;j<nodes.size();j++){
				FlibHENode n=nodes.get(j);
				if (indnodes.contains(n)){
					FlibHENode newN=new FlibHENode(n.x,n.y);
					indnodes.add(newN);
				}
				else{
					indnodes.add(n);
				}
			}
			if (indnodes.size()>3){
			Triangulator tri=new Triangulator(indnodes);
			tri.triangulate();
			
			for (int j=0;j<tri.edges.size();j++){
				Object[] edge=tri.edges.get(j);
				FlibHEdge hEdge=new FlibHEdge((FlibHENode)edge[0],(FlibHENode)edge[1]);
				triangulate.add(hEdge);
			}
			triangles.addAll(tri.triangles);
			}
		}
	}
	public void displayDetail(PGraphics g){
		for (int i=0;i<walls.size();i++){
			FlibWall wall=walls.get(i);
			Vec2D[] footprint=wall.calculateFootPrint();
			g.beginShape();
			for (int j=0;j<footprint.length;j++){
				Vec2D v=footprint[j];
				g.vertex(v.x,v.y);
			}
			g.endShape(PGraphics.CLOSE);
		}
	}
	public Vector<FlibHEdge>getAllHEdges(){
		Vector<FlibHEdge>hEdges=new Vector<FlibHEdge>();
		for (int i=0;i<walls.size();i++){
			FlibWall wall=walls.get(i);
			hEdges.add(wall.hEdge);
			hEdges.add(wall.hEdge.getSym());
		}
		return hEdges;
	}
	
}
